#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/irq.h>
// #include <linux/napi.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

//为什么insmod一直卡着不动呢？
// //因为napi_struct结构体没有定义，所以编译不通过，所以insmod一直卡着不动
// //解决办法：将napi_struct结构体定义在本文件中
// struct napi_struct {
//     int dummy;
// };

static struct napi_struct my_napi;

// 轮询函数
static int my_napi_poll(struct napi_struct *napi, int budget)
{
    int work_done = 0;

    // 处理接收到的数据包
    while (work_done < budget) {
        // 假设从硬件设备读取数据包
        struct sk_buff *skb = alloc_skb(ETH_FRAME_LEN, GFP_ATOMIC);
        if (!skb) {
            break;
        }

        // 填充数据包内容
        skb_put(skb, ETH_FRAME_LEN);
        memset(skb->data, 0x55, ETH_FRAME_LEN);

        // 将数据包传递给网络栈
        if (netif_receive_skb(skb) == NET_RX_DROP) {
            printk(KERN_ERR "Failed to pass skb to network stack.\n");
        }

        work_done++;
    }

    // 如果没有处理完所有数据包，重新调度轮询
    if (work_done < budget) {
        napi_complete(napi);
    }

    return work_done;
}

// 中断处理程序
static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
{
    // 调度轮询操作
    napi_schedule(&my_napi);

    return IRQ_HANDLED;
}

static int __init netif_receive_skb_demo_init(void)
{
    int irq = 19;  // 假设中断号为 19
    int ret;

    // 初始化 NAPI 结构体
    netif_napi_add(NULL, &my_napi, my_napi_poll, 64);

    // 注册中断处理程序
    ret = request_irq(irq, my_interrupt_handler, IRQF_SHARED, "my_netif_receive_skb", NULL);
    if (ret < 0) {
        printk(KERN_ERR "Failed to register IRQ %d.\n", irq);
        return ret;
    }

    printk(KERN_INFO "netif_receive_skb demo module loaded.\n");
    return 0;
}

static void __exit netif_receive_skb_demo_exit(void)
{
    int irq = 19;  // 假设中断号为 19

    // 注销中断处理程序
    free_irq(irq, NULL);

    // 移除 NAPI 结构体
    netif_napi_del(&my_napi);

    printk(KERN_INFO "netif_receive_skb demo module unloaded.\n");
}

module_init(netif_receive_skb_demo_init);
module_exit(netif_receive_skb_demo_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple module to demonstrate netif_receive_skb.");
MODULE_AUTHOR("Your Name");


